package com.d3works.apps.crm.service;

import com.d3works.apps.base.db.Address;
import com.d3works.apps.base.db.Company;
import com.d3works.apps.base.db.Partner;
import com.d3works.apps.base.db.repo.SequenceRepository;
import com.d3works.apps.base.service.AddressService;
import com.d3works.apps.base.service.PartnerService;
import com.d3works.apps.base.service.administration.SequenceService;
import com.d3works.apps.crm.db.Lead;
import com.d3works.apps.crm.db.Opportunity;
import com.d3works.apps.crm.db.repo.OpportunityRepository;
import com.d3works.apps.crm.exception.CrmExceptionMessage;
import com.d3works.apps.message.db.EmailAddress;
import com.d3works.exception.D3worksException;
import com.d3works.exception.db.repo.TraceBackRepository;
import com.d3works.i18n.I18n;
import com.d3works.inject.Beans;
import com.google.inject.Inject;
import com.google.inject.persist.Transactional;

public class OpportunityServiceImpl implements OpportunityService {

  @Inject protected OpportunityRepository opportunityRepo;

  @Inject protected AddressService addressService;

  @Transactional
  public void saveOpportunity(Opportunity opportunity) {
    opportunityRepo.save(opportunity);
  }

  @Override
  @Transactional(rollbackOn = {Exception.class})
  public Partner createClientFromLead(Opportunity opportunity) throws D3worksException {
    Lead lead = opportunity.getOpportunityLead();
    if (lead == null) {
      throw new D3worksException(
          opportunity,
          TraceBackRepository.CATEGORY_CONFIGURATION_ERROR,
          I18n.get(CrmExceptionMessage.LEAD_PARTNER));
    }

    String name = lead.getFullName();

    Address address = null;
    if (lead.getPrimaryAddress() != null) {
      // avoids printing 'null'
      String addressL6 =
          lead.getPrimaryPostalCode() == null ? "" : lead.getPrimaryPostalCode() + " ";
      addressL6 += lead.getPrimaryCity() == null ? "" : lead.getPrimaryCity().getName();

      address =
          addressService.createAddress(
              null, null, lead.getPrimaryAddress(), null, addressL6, lead.getPrimaryCountry());
      address.setFullName(addressService.computeFullName(address));
    }

    EmailAddress email = null;
    if (lead.getEmailAddress() != null) {
      email = new EmailAddress(lead.getEmailAddress().getAddress());
    }

    Partner partner =
        Beans.get(PartnerService.class)
            .createPartner(
                name,
                null,
                lead.getFixedPhone(),
                lead.getMobilePhone(),
                email,
                opportunity.getCurrency(),
                address,
                address,
                true);

    opportunity.setPartner(partner);
    opportunityRepo.save(opportunity);

    return partner;
  }

  @Override
  public void setSequence(Opportunity opportunity) throws D3worksException {
    Company company = opportunity.getCompany();
    String seq =
        Beans.get(SequenceService.class)
            .getSequenceNumber(
                SequenceRepository.OPPORTUNITY, company, Opportunity.class, "opportunitySeq");
    if (seq == null) {
      throw new D3worksException(
          TraceBackRepository.CATEGORY_CONFIGURATION_ERROR,
          I18n.get(CrmExceptionMessage.OPPORTUNITY_1),
          company != null ? company.getName() : null);
    }
    opportunity.setOpportunitySeq(seq);
  }
}
